package com.selvn.encryptnote;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.app.ListActivity;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RemoteViews;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import com.selvn.tool.SimpleCrypto;

public class NoteList extends ListActivity {
    private static final int ACTIVITY_CREATE=0; 
    private static final int ACTIVITY_EDIT=1;
    private static final int ACTIVITY_CHANGEPASSWORD=2;
    
    private static final int DELETE_ID = Menu.FIRST;
    private static final int SETTIP = Menu.FIRST + 5;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /*
        FragmentManager fm = getFragmentManager();
        // Create the list fragment and add it as our sole content.
        if (fm.findFragmentById(android.R.id.content) == null) {
            CursorLoaderListFragment list = new CursorLoaderListFragment();
            fm.beginTransaction().add(android.R.id.content, list).commit();
        }
         */
		setContentView(R.layout.notes_list);
		initOrderSpinner();        
		
        FillData();
        EditText et = (EditText)findViewById(R.id.SearchBox);
        // 监听搜索变化
        et.addTextChangedListener(watcher);
        registerForContextMenu(getListView());
        
    }
    
    private void initOrderSpinner()
	{
		// init orderby
		Spinner spinner = (Spinner) findViewById(R.id.spinner_orderby);
		List<SpinnerData> spList = new ArrayList<SpinnerData>();
		spList.add(new SpinnerData(this.getString( R.string.orderByTitle ), Config.DBTITLE + " ASC"));
		spList.add(new SpinnerData(this.getString( R.string.orderByCreate ), Config.DBCREATEDATE + " DESC"));
		spList.add(new SpinnerData(this.getString( R.string.orderByModify ), Config.DBMODIFY + " DESC"));
		// Create an ArrayAdapter using the string array and a default spinner
		// layout
		ArrayAdapter<SpinnerData> adapter = new ArrayAdapter<SpinnerData>(this, android.R.layout.simple_spinner_item, spList);
		// Specify the layout to use when the list of choices appears
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		// Apply the adapter to the spinner
		spinner.setAdapter(adapter);
		// 监听菜单变化
		spinner.setOnItemSelectedListener(new SpinnerActivity());
    }
    private String order()
    {
    	Spinner spinner = (Spinner) findViewById(R.id.spinner_orderby);
    	return ((SpinnerData)spinner.getSelectedItem()).getValue();
    }
    // 监听下拉菜单变化
    public class SpinnerActivity extends Activity implements OnItemSelectedListener {
        
        public void onItemSelected(AdapterView<?> parent, View view, 
                int pos, long id) {
            // An item was selected. You can retrieve the selected item using
            //Toast.makeText(parent.getContext(), parent.getItemAtPosition(pos).toString(), Toast.LENGTH_SHORT).show(); 
        	FillData();
        }

        public void onNothingSelected(AdapterView<?> parent) {
            // Another interface callback
        }
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	super.onCreateOptionsMenu(menu);
        //menu.add(0, BACKUP, 0, R.string.backup).setIcon(android.R.drawable.ic_menu_save);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_list, menu);
        return super.onCreateOptionsMenu(menu);
    }
    
    // 主菜单被点击时调用这里
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	Log.i(Config.LOGTAG,"-----");
        switch (item.getItemId()) {
            case R.id.Menu_AddNew:
            	createNote(null);
            	return true;
            case R.id.Menu_ChangePassword:
                Intent i = new Intent(this, ChangePassword.class);
                startActivityForResult(i, ACTIVITY_CHANGEPASSWORD);
                break;
            case R.id.Menu_Backup:
            	int flag_backup = Backup();
            	Func.handle_return_code(this, flag_backup);
                break;
            case R.id.Menu_Restore:
            	int flag = Restore();
            	Func.handle_return_code(this, flag);
            	if( flag == Config.RESTORE_SUCCEED )
            	{
            		FillData();
            	}
                break;
            case R.id.Menu_About:
                Func.MessageBox(this, R.string.aboutDescription, R.string.about, R.string.confirm);
                break;
            default:
                return super.onOptionsItemSelected(item);
        }
        return false;
    }    
    private TextWatcher watcher = new TextWatcher(){
        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,  
                int after) {  
            // TODO Auto-generated method stub  
        }  
        @Override  
        public void onTextChanged(CharSequence s, int start, int before,  
                int count) {
            //String searchString = s.toString();
        	FillData();
        }  
    };
    
    public void FillData()
    {
    	EditText SearchBox = (EditText)findViewById(R.id.SearchBox);  
        String searchString = SearchBox.getText().toString().trim();
        ArrayList<HashMap<String, String>> notesList = null;
        if( TextUtils.isEmpty( searchString ) )
        {
        	notesList = NoteModel.getNotes(this, order());
        }
        else
        {
        	String selection = Config.DBTITLE + " like '%" + searchString + "%' or " + Config.DBBODY + " like '%" + searchString + "%'";
            notesList = NoteModel.getNotes(this, selection, order() );//mDbHelper.FetchSearchNotes(searchString);
        }
        
        BindNoteList( notesList);
    }
    
    public void BindNoteList( ArrayList<HashMap<String, String>> notesList ) 
    {
        // Create an array to specify the fields we want to display in the list (only TITLE)
        String[] from = new String[]{
        		Config.DBTITLE,
        		Config.DBCREATEDATE,
        };
        // and an array of the fields we want to bind those fields to (in this case just text1)
        int[] to = new int[]{R.id.text1, R.id.date1};
        
        // Now create a simple cursor adapter and set it to display
        SimpleAdapter notes = new SimpleAdapter(this, notesList, R.layout.notes_row, from, to);
        setListAdapter(notes);
    }
	
    @Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, SETTIP, 0, R.string.setTip).setIcon(android.R.drawable.ic_menu_gallery);
        menu.add(0, DELETE_ID, 1, R.string.menu_delete).setIcon(android.R.drawable.ic_menu_delete);
	}

    @Override
	public boolean onContextItemSelected(MenuItem item) {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        Adapter adapter = getListAdapter();
        @SuppressWarnings("unchecked")
		HashMap<String, String> noteHashMap = ( HashMap<String, String> )adapter.getItem(info.position);
        String noteIdString = noteHashMap.get( Config.DBID );
		switch(item.getItemId()) {
    	case DELETE_ID:
    		NoteModel.delete(this, Long.parseLong(noteIdString) );
	        FillData();
	        break;
    	case SETTIP:
            String tipText = noteHashMap.get(Config.DBBODY);
    	    Func.WriteFileToInternal(this, Config.TIPPATH, tipText);
    	    
    	    AppWidgetManager awm = AppWidgetManager.getInstance(this);  
    	    RemoteViews views = new RemoteViews(this.getPackageName(),R.layout.notewidget);  
    	    
    	    views.setTextViewText(R.id.tip, tipText);  
    	    
    	    awm.updateAppWidget(new ComponentName(this, MyAppWidgetProvider.class), views);
    	    Toast.makeText(this, R.string.tipSetMessage, Toast.LENGTH_LONG).show();
    	    break;
		}
		return super.onContextItemSelected(item);
	}
	
    public void createNote( View v) {
        Intent i = new Intent(this, NoteEdit.class);
        startActivityForResult(i, ACTIVITY_CREATE);
    }
    
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        //获取被点击的item所对应的数据  
        @SuppressWarnings("unchecked")
		HashMap<String,String> map = (HashMap<String, String>)l.getItemAtPosition(position);

        Intent i = new Intent(this, NoteEdit.class);
        i.putExtra(Config.DBID,Long.parseLong( map.get(Config.DBID) ));
        startActivityForResult(i, ACTIVITY_EDIT);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, 
                                    Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        switch ( requestCode )
        {
        case ACTIVITY_CREATE:
        case ACTIVITY_EDIT:
            if( resultCode == RESULT_OK )
            {
                Toast.makeText(getApplicationContext(), R.string.save_succeed, Toast.LENGTH_LONG).show();
            }
            break;
        case ACTIVITY_CHANGEPASSWORD:
            if( resultCode == RESULT_OK )
            {
                //MessageBox( R.string.pwChangedMessage, R.string.pwChangedTitle, R.string.confirm );
                Toast.makeText(getApplicationContext(), R.string.pwChangedMessage, Toast.LENGTH_LONG).show();
            }
            break;
        }
        FillData();
    }
    
    private int Backup()
	{
    	if( !Func.isExternalStorageAvailable() )
    	{
    		return Config.BACKUP_FAILED_NO_EXTERNAL;
    	}
		String noteListXmlString = NoteModel.GetListXml(this);
		String saveString = "<r>" + noteListXmlString + Config.GetBackupXml()+"</r>";
		String cryptoString = "";
		try
		{
			cryptoString = SimpleCrypto.encrypt("aaasds", saveString);
		}
		catch (Exception e)
		{
			cryptoString = "";
			return Config.BACKUP_FAILED_ENCRYPT_ERROR;
		}
		
		if( !Func.WriteFile(Config.BACKUPPATH, cryptoString ) )
		{
			return Config.BACKUP_FAILED;
		}
		// 删掉旧版本备份文件, 如果成功出现提示
		if( Func.DeleteFile( Config.BACKUPPATH_BEFORE ) )
		{
			Toast.makeText(this, "旧版本备份文件已被删除", Toast.LENGTH_SHORT).show();
		}
    	
    	return Config.BACKUP_SUCCEED;
	}
    
    private int Restore()
    {
        String clearString = Func.ReadFile( Config.BACKUPPATH);
        // 没有找到新格式的备份文件, 尝试找旧格式的备份文件
        if( TextUtils.isEmpty( clearString ) )
        {
        	clearString = Func.ReadFile( Config.BACKUPPATH_BEFORE );
        }
        else {
        	try
    		{
            	clearString = SimpleCrypto.decrypt("aaasds", clearString);
    		} 
            catch (Exception e)
    		{
    		}
		}
        if( TextUtils.isEmpty(clearString))
        {
        	return Config.RESTORE_FAILED_NOFILEFOUND;
        }
        List<HashMap<String, String>> notesList = null;
        try
        {
        	EncryptNoteXmlParser encryptNoteXmlParser = new EncryptNoteXmlParser();
        	InputStream in = new ByteArrayInputStream(clearString.getBytes());
        	notesList = encryptNoteXmlParser.parse(in);
        	/*
            SAXHandler myHandler = new SAXHandler(this);
                        
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser saxParser = spf.newSAXParser();

            XMLReader xmlReader = saxParser.getXMLReader();
            xmlReader.setContentHandler(myHandler);
            
            StringReader sr = new StringReader(clearString);
            InputSource is = new InputSource(sr);
            xmlReader.parse(is);
            //android.util.Xml.parse(fis, Xml.Encoding.UTF_8, myHandler);
            //data = buffer.toString();
             * 
             */
        }
        catch (Exception e )
        {
            return Config.RESTORE_PARSE_FAILED;
            //Func.Toast(this, e.getMessage());
        }
        for (HashMap<String, String> hashMap : notesList)
		{
			ContentValues values = new ContentValues();
			values.put(Config.DBTITLE, hashMap.get(Config.DBTITLE));
			values.put(Config.DBBODY, hashMap.get(Config.DBBODY));
			values.put(Config.DBCREATEDATE, hashMap.get(Config.DBCREATEDATE));
			values.put(Config.DBMODIFY, hashMap.get(Config.DBMODIFY));
			values.put(Config.DBLOCATION1, hashMap.get(Config.DBLOCATION1));
			values.put(Config.DBLOCATION2, hashMap.get(Config.DBLOCATION2));
			NoteModel.insert(this, values);
		}
        return Config.RESTORE_SUCCEED;
        //Log.i("Restore", data);
        //Func.Toast(this, data);
    }
}
